---------Creatures of the Night--------
A 4am crack                  2015-12-18
---------------------------------------

Name: Creatures of the Night
Genre: educational
Year: 1984
Publisher: Troll Associates
Media: single-sided 5.25-inch floppy
OS: DOS 3.3
Previous cracks: none
Identical cracks:
  #527 Birds
  #521 Introduction to Counting
  #510 KidWriter 1.0
  #468 Reading Fun: Beginning Consonant
       Sounds
  #456 Adding Fractions
  #437 Word Master
  #412 Math Class Level 5

                   ~

               Chapter 0
 In Which Various Automated Tools Fail
          In Interesting Ways


COPYA
  immediate disk read error

Locksmith Fast Disk Backup
  unable to read any track

EDD 4 bit copy (no sync, no count)
  no errors, but copy grinds on boot

Copy ][+ nibble editor
  modified address epilogue "AF FF FF"
  odd-numbered tracks (1, 3, 5...) also
    have a modified address prologue
    ("D4 AA 96")

Disk Fixer
  ["O" -> "Input/Output Control"]
  set Address Epilogue to "AF FF FF"
  -> even-numbered tracks readable
  T00 looks like a DOS 3.3 RWTS
  set Address Prologue to "D4 AA 96"
  -> odd-numbered tracks also readable
  T01 readable. Also T03, T05, T07...
  T11 looks like a DOS 3.3 disk catalog
  T01,S09 -> startup program is "HELLO"

Why didn't COPYA work?
  modified prologue and epilogue

Why didn't Locksmith FDB work?
  modified prologue and epilogue

Why didn't my EDD copy work?
  I don't know. Maybe a nibble check
  during boot?

Next steps:

  1. capture RWTS with AUTOTRACE
  2. convert disk to standard format
     with Advanced Demuffin
  3. patch RWTS to read demuffin'd disk
  4. find the nibble check & bypass it
  5. declare victory(*)

(*) Take a nap.

                   ~

               Chapter 1
         Bit Math Is Best Math


[S6,D1=original disk]
[S6,D2=blank disk]
[S5,D1=my work disk]

]PR#5
...
CAPTURING BOOT0
...reboots slot 6...
...reboots slot 5...
SAVING BOOT0
/!\ BOOT0 JUMPS TO $08F0
CAPTURING BOOT1
...reboots slot 6...
...reboots slot 5...
SAVING BOOT1
SAVING RWTS

]BLOAD BOOT0,A$800
]CALL -151
*801L
.
. all normal until...
.
084A-   4C F0 08    JMP   $08F0

*8F0L

08F0-   A9 AA       LDA   #$AA
08F2-   85 31       STA   $31
08F4-   A9 00       LDA   #$00
08F6-   8D F1 B6    STA   $B6F1
08F9-   4C 00 B7    JMP   $B700

I've seen this before. The RWTS uses
zero page $31 to check the second byte
of the address (or data (or both))
prologue (or epilogue (or both)).

*BLOAD RWTS,A$2800
*FE89G FE93G     ; disconnect DOS
*B800<2800.2FFFM ; move RWTS into place

*B944L

; routine to read address prologue
B944-   A0 FC       LDY   #$FC
B946-   84 26       STY   $26
B948-   C8          INY
B949-   D0 04       BNE   $B94F
B94B-   E6 26       INC   $26
B94D-   F0 F3       BEQ   $B942
B94F-   BD 8C C0    LDA   $C08C,X
B952-   10 FB       BPL   $B94F

; find prologue nibble #1
B954-   4A          LSR
B955-   C9 6A       CMP   #$6A
B957-   D0 EF       BNE   $B948
B959-   BD 8C C0    LDA   $C08C,X
B95C-   10 FB       BPL   $B959

; find #2
B95E-   C5 31       CMP   $31     <-- !
B960-   D0 F2       BNE   $B954
B962-   A0 03       LDY   #$03
B964-   BD 8C C0    LDA   $C08C,X
B967-   10 FB       BPL   $B964

; find #3
B969-   C9 96       CMP   #$96
B96B-   D0 E7       BNE   $B954

Well this just answers a whole slew of
questions at once.

The code to find prologue nibble #1
explains how this disk can read its
odd-numbered tracks (with non-standard
address prologue "D4 AA 96").

Normal address prologue byte 1 is $D5.
In binary: $D5 = 1101 0101
After LSR:       0110 1010 = $6A

Odd-numbered tracks use $D4 instead.
In binary: $D4 = 1101 0100
After LSR:       0110 1010 = $6A

So this code will match either prologue
and work on both odd and even tracks.

Furthermore, RWTS code is time-critical
between reading the last bit of one
nibble and reading the first bit of the
next. If it's too fast or too slow, it
will get out of phase (because the disk
spins independently of the CPU).

Compare DOS 3.3 (cycle count in margin)

B94F-   BD 8C C0    LDA   $C08C,X
B952-   10 FB       BPL   $B94F
B954-   C9 D5       CMP   #$D5    | 2
B956-   D0 F0       BNE   $B948   | 2 *
B958-   EA          NOP           | 2
B959-   BD 8C C0    LDA   $C08C,X
B95C-   10 FB       BPL   $B959

(*) on the time-critical path, this
    branch is not taken, so always 2

...and this disk's RWTS:

B94F-   BD 8C C0    LDA   $C08C,X
B952-   10 FB       BPL   $B94F
B954-   4A          LSR           | 2
B955-   C9 6A       CMP   #$6A    | 2
B957-   D0 EF       BNE   $B948   | 2 *
B959-   BD 8C C0    LDA   $C08C,X
B95C-   10 FB       BPL   $B959

Despite being more "flexible" (matching
$D5 or $D4), this disk's RWTS uses the
same number of bytes of code and runs
in the same number of cycles. Nice.

Furthermore, look at this code to match
nibble #2 of the address prologue:

*B959L

B959-   BD 8C C0    LDA   $C08C,X
B95C-   10 FB       BPL   $B959
B95E-   C5 31       CMP   $31     <-- !
B960-   D0 F2       BNE   $B954

There's zero page $31, initialized at
$BB00 during boot.

Solution: an IOB module that Advanced
Demuffin calls before calling the
original disk's RWTS. (Read the docs on
my work disk.)

                   ~

               Chapter 2
In Which We Attempt To Use The Original
    Disk As A Weapon Against Itself


*C500G
...
]CALL -151
]BLOAD ADVANCED DEMUFFIN 1.5

; standard Advanced Demuffin setup
; (unchanged)
1400-   4A          LSR
1401-   8D 22 0F    STA   $0F22
1404-   8C 23 0F    STY   $0F23
1407-   8E 27 0F    STX   $0F27
140A-   A9 01       LDA   #$01
140C-   8D 20 0F    STA   $0F20
140F-   8D 2A 0F    STA   $0F2A

; initialize zero page used by the RWTS
1412-   A9 AA       LDA   #$AA
1414-   85 31       STA   $31

; call RWTS
1416-   A9 0F       LDA   #$0F
1418-   A0 1E       LDY   #$1E
141A-   4C 00 BD    JMP   $BD00

*BSAVE IOB $31,A$1400,L$FB

*BRUN ADVANCED DEMUFFIN 1.5

["5" to switch to slot 5]

["R" to load a new RWTS module]
  --> At $B8, load "RWTS" from drive 1

[press "I" to load a new IOB module]
  --> load "IOB $31" from drive 1

["6" to switch to slot 6]

["C" to convert disk]

                 --v--

ADVANCED DEMUFFIN 1.5    (C) 1983, 2014
ORIGINAL BY THE STACK    UPDATES BY 4AM
=======PRESS ANY KEY TO CONTINUE=======
TRK:...................................
+.5:
    0123456789ABCDEF0123456789ABCDEF012
SC0:...................................
SC1:...................................
SC2:...................................
SC3:...................................
SC4:...................................
SC5:...................................
SC6:...................................
SC7:...................................
SC8:...................................
SC9:...................................
SCA:...................................
SCB:...................................
SCC:...................................
SCD:...................................
SCE:...................................
SCF:...................................
=======================================
16SC $00,$00-$22,$0F BY1.0 S6,D1->S6,D2

                 --^--

]PR#5
...
]CATALOG,S6,D2

C1983 DSR^C#254
028 FREE

 A 002 HELLO
 A 007 MASTERX
*B 004 ADDRESS
*B 002 TOTB
*B 007 NONT
 A 009 MENU
*B 002 MOVER.SEL
*B 034 LOGO4
*B 003 MUSIC.DATA
 B 034 GAME.MENU
 A 023 THE.SM7
*B 006 HELPER
*B 034 NYMT
 A 013 NYM.FP4
*B 034 P2.NYM
*B 007 SHAPE.TBLS
 B 011 APPLE
*B 034 SM1.1
 B 002 SM.MOVER.V
 B 007 SS
*B 009 DRAW
*B 002 MOVER.NYM
*B 006 PLOT
*B 002 DRAWS
*B 013 DRAWDATA
*B 005 RATTLERTEXT
*B 020 U2
*B 020 NYMSCROLL
*B 015 AJMAZE2
*B 011 AJMAZE1
*B 012 AJC/N.SH.0
*A 003 REPMAZE
*A 002 VARIABLE
*B 023 ICR CN2
*B 012 BIRD.SH
*B 034 COTN2.PIC
*B 002 NYM.RAN
*B 002 VAR.RAN

]RUN HELLO
...works...

[S6,D1=demuffin'd copy]

]PR#6
...works...

Wait, what?

                   ~

               Chapter 3
  In Which We Angrily Investigate Why
    We Suddenly Have A Working Copy


[S6,D1=mysteriously working copy]
[S5,D1=my work disk]

]PR#5
]BLOAD RWTS,A$2800
]CALL -151

*FE89G FE93G
*B800<2800.2FFFM

*B944L
.
. all weirdness accounted for, until...
.
; find epilogue byte #1
B98B-   BD 8C C0    LDA   $C08C,X
B98E-   10 FB       BPL   $B98B
B990-   C9 DE       CMP   #$DE

; if found $DE, immediately exit with
; a "success" status (clear carry bit)
B992-   F0 0A       BEQ   $B99E

; if not $DE, do... this thing
B994-   48          PHA
B995-   68          PLA
B996-   BD 8C C0    LDA   $C08C,X

; Note: no BPL loop here! It only reads
; the data latch once.
B999-   C9 08       CMP   #$08
B99B-   B0 A5       BCS   $B942
B99D-   EA          NOP
B99E-   18          CLC
B99F-   60          RTS

It's looking for a timing bit after the
first epilogue byte. It doesn't even
care what the first epilogue byte was,
as long as it wasn't $DE.

This RWTS will accept two different
address prologues, "D5 AA 96" or "D4 AA
96". It will also accept two different
address epilogues, "DE" or anything-
other-than-DE-followed-by-a-timing-bit.

Why didn't the EDD copy work?
  EDD preserved the original prologue
  epilogue but not the timing bits.
  The prologue checker (at $B944) finds
  "D5 AA 96" (even-numbered tracks) or
  "D4 AA 96" (odd-numbered tracks). But
  the epilogue checker's first compare
  (at $B98B) didn't match because the
  first epilogue byte was still the
  original value ($AF), and its second
  compare (at $B999) didn't match
  because there was no timing bit after
  the first byte. There was never any
  separate nibble check; the structure
  of the disk itself is designed to
  foil nibble copiers.

Why did the demuffin'd copy work?
  Advanced Demuffin wrote out the data
  from each sector onto a standard disk
  that uses "D5 AA 96" prologue and "DE
  AA EB" epilogue. The RWTS always
  matches "D5 AA 96" and doesn't care
  that it never sees a "D4 AA 96" for a
  prologue. The epilogue checker always
  matches "DE" and never checks the
  timing bit. Thus, no RWTS patches are
  necessary.

Quod erat liberandum.

---------------------------------------
A 4am crack                     No. 528
------------------EOF------------------
